#ifndef COMM_H
#define COMM_H

#include <QTypeInfo>

#define I2V (float(46.96f) / 4095)

/*
 * Status Flags
 * Bit0 = Safety Charge
 * Bit8 = Charge/Discharge Complete
 * Bit11 = Reduce Amps
 * Bit14 = Node Only Charging (3A max current)
 *
 */
#define ST_SAFETY_CHARGE_BIT     0
#define ST_CHG_DSCH_COMPLETE_BIT 8
#define ST_REDUCE_AMPS_BIT       11
#define ST_NODE_ONLY_CHRG_BIT    14


/*
 * RX Status Flags
 * Bit1 = Discharge Running
 * Bit4 = Regenerative Discharge
 * Bit6 = Charge Running
 * Bit7 = Balancers Running
 *
 */
#define RXS_DSCH_RUNNING_BIT      1
#define RXS_REGEN_DISCHARGE_BIT   4
#define RXS_CHG_RUNNING_BIT       6
#define RXS_BALANCERS_RUNNING_BIT 7


/*
 * Status 2 Flags
 * Bit2 = High Temp (140 deg F)
 *
 */
#define ST2_HIGH_TEMP_BIT   2

/*
 * Status 6 Flags
 * Bit4 = Constant Voltage
 * Bit5 = Preset is Valid and Runable
 * Bit8 = Regenerative Discharge Failed
 *
 */
#define ST6_CONSTANT_VOLTAGE_BIT             4
#define ST6_PRESET_IS_VALID_AND_RUNABLE_BIT  5
#define ST6_REGEN_DISCHARGE_FAILED_BIT       8

/*
 * mode Register
 * 0 = Charger Ready to Start
 * 1 = Detecting Pack
 * 6 = Charging
 * 7 = Trickle Charging
 * 8 = Discharging
 * 9 = Monitoring
 * 10 = Halt for Safety Screen
 * 11 = Pack Cool Down (when cycling)
 * 99 = System Stop Error Occurred
 *
 */
#define MODE_CHARGER_READY_TO_START         0
#define MODE_DETECTING_PACK                 1
#define MODE_CHARGING                       6
#define MODE_TRICKLE_CHARGING               7
#define MODE_DISCHARGING                    8
#define MODE_MONITORING                     9
#define MODE_HALT_FOR_SAFETY_SCREEN         10
#define MODE_PACK_COOL_DOWN                 11
#define MODE_SYSTEM_STOP_ERROR_OCCURED      99

/*
 * Chemistry Register
 * 1 = Lithium Polymer
 * 2 = Lithium Ion
 * 3 = A123
 * 4 = Lithium Manganese
 * 5 = Lithium Cobalt
 * 6 = NiCd
 * 7 = NiMh
 * 8 = Lead Acid
 * 9 = LiFE
 * 10 = Primary
 * 11 = Power Supply
 *
 */
#define CHEMISTRY_LITHIUM_POLYMER         1
#define CHEMISTRY_LITHIUM_ION             2
#define CHEMISTRY_A123                    3
#define CHEMISTRY_LITHIUM_MANGANESE       4
#define CHEMISTRY_LITHIUM_COBALT          5
#define CHEMISTRY_NICD                    6
#define CHEMISTRY_NIMH                    7
#define CHEMISTRY_LEAD_ACID               8
#define CHEMISTRY_LIFE                    9
#define CHEMISTRY_PRIMARY                 10
#define CHEMISTRY_POWER_SUPPLY            11


/*
 * Power Reduced Reason
 * 0 = Full Power Allowed
 * 1 = Input Current Limit
 * 2 = 60A Input Current Limit Reached
 * 3 = Cell Sum Error (Charge)
 * 4 = Supply Noise
 * 5 = High Temp
 * 6 = Low Input Voltage
 * 7 = Constant Voltage Output
 * 8 = Internal Max 100W Discharge
 * 9 = High Temp Discharge
 * 10 = Regen. Max Amps Reached
 * 11 = High Temp Discharge
 * 12 = Cell Sum Error (Discharge)
 * 13 = Regen. Volt Limit Reached
 * 14 = Discharge Reduced (Below Average Charger)
 * 15 = Reduce (Above Average Charger)
 * 16 = Supply Low for High Power
 *
 */
#define PRR_FULL_POWER_ALLOWED                0
#define PRR_INPUT_CURRENT_LIMIT               1
#define PRR_60A_LIMIT_INPUT_CURRENT_REACHED   2
#define PRR_CELL_SUM_ERROR                    3
#define PRR_SUPPLY_NOISE                      4
#define PRR_HIGH_TEMP                         5
#define PRR_LOW_INPUT_VOLTAGE                 6
#define PRR_CONSTANT_VOLTAGE_OUTPUT           7
#define PRR_INTERNAL_MAX_100W_DISCHARGE       8
#define PRR_HIGH_TEMP_DISCHARGE               9
#define PRR_REGEN_MAX_AMPS_REACHED            10
#define PRR_HIGH_TEMP_DISCHARGE2              11
#define PRR_CELL_SUM_ERROR2                   12
#define PRR_REGEN_VOLT_LIMIT_REACHED          13
#define PRR_DISCHARGE_REDUCED                 14
#define PRR_REDUCE                            15
#define PRR_SUPPLY_LOW_FOR_HIGH_POWER         16


/*
 * Ram Packet
 * Ram – Quarries the PowerLab 8 for a PowerLab 8 status packet
 * Send the "Ram" command followd by the charger ID (1 byte: 0..16)
 *
 * Verify chksum
 */
typedef struct t_RamPacket {
    char           cmd[4]; // should hold: 0,0,'R','a','m',0 after reading
    quint8         chargerID;
    qint16         fwVersion; //0.00 thru 655.35
    quint16        cellVolt[8]; //Volts = 16bit * 5.2V / 65536
    quint16        syncPWMDrive; //0-8191 is Buck, 8192-16383 is Boost
    qint16         chargeCurrentSetPoint; //Only Valid when Charging | Amps = 16bit / 1666
    qint16         supplyVoltsWCurrent; //Volts = 16bit * 46.96V / 4095 / 16
    qint16         supplyVolts; //Volts = 16bit * 46.96V / 4095
    qint16         cpuTemp; //Tc = (2.5 * 16bit / 4095 - 0.986) / 0.00355
    quint16        chargeSec; //0 to 18*3600 (Use with charge minutes)
    qint16         fastApmsReading; //Amps = 16bit signed / 600
    qint16         outputPositiveReading; //Volts = 46.96V / 4095
    qint32         mahInToBattery; //mAh = 32bit / 2160
    qint16         avgFuel; // Fuel% = 16bit / 10
    qint16         startFuel; // Fuel% = 16bit / 10
    qint16         avgAmpsReading; //Amps = 16bit / 600
    quint16        statusFlags; // bits described above
    quint16        rxStatusFlags; // bits described above
    qint16         n_u1;
    quint16        status2Flags;  // bits described above
    qint16         cellInternalResistence[8]; //mOhm = ( 16bit / 6.3984 – VROffset ) / VRAmps
    qint16         vrAmps; // Amps = 16bit / 600
    qint16         nicdFallbackVolts; // Volts = 16bit / 12797 - MaxCell
    qint16         n_u2;
    qint16         maxCellVolts; // Volts = 16bit / 12797
    quint16        status6Flags;  // bits described above
    quint16        chargeMin; // For <18hr use ChgSec | For >=18hr Seconds = ChgSec – 64800 + ChgMin * 60
    qint16         supplyAmps; // Amps = 16bit / 150
    qint16         batteryPositive; // Volts = 16bit / 12797
    qint32         mahOutOfBattery; // mAh = 32bit / 2160
    qint16         n_u3;
    qint16         regenVoltSetPoint; // Volts = 16bit * 46.96V / 4095
    qint16         dischargeSetAmps; // Amps = 16bit / 600
    quint16        internalDischargePWM; // 0 – 8192
    qint16         negativeNodeVoltDrop; // Volts = 16bit * 46.96V / 4095
    qint16         positiveNodeVoltDrop; // Volts = 16bit * 46.96V / 4095
    qint16         batteryNegative; // Volts = 16bit * 46.96V / 4095
    qint16         n_u4;
    qint16         startSupplyVolts; // Volts = 16bit * 46.96V / 4095
    qint16         n_5;
    qint16         n_6;
    qint16         n_7;
    qint16         n_8;
    qint16         vrOffset; // mV = 16bit / 6.3984
    qint16         slowAvgAmps; // Amps = 16bit / 600
    qint16         presetSetChargeAmps; // Amps = 16bit / 600 (never changes with temp or power)
    qint16         n_u9;
    qint16         n_u10;
    quint8         balancerPWM[8]; // 0..31
    quint8         detectedCellCount; // 1 – 8 (0 = no cells detected)
    quint8         mode; // described above
    quint8         errorCode;  // Only valid in Mode 99
    quint8         chemistry;  // described above
    qint8          n_u11;
    quint8         loadedPresetNumber; // 0 – 24 (Zero based number: 1..25)
    qint8          n_u12;
    quint8         screenNumber; // Screen showing on LCD
    qint8          n_u13;
    qint8          n_u14;
    quint8         cycleNumber; // 0 – 255 (A complete Charge/Discharge is one cycle)
    quint8         powerReducedReason; // described above
    qint8          n_u15;
    qint8          n_u16;
    qint8          n_u17;
    quint16        crcChecksum;
} __attribute__((packed)) RamPacket;

#define PRESET_STRUCT_LEN   102
#define PRESET_NUM          25
#define PRESET_READ_BUF_HEADER 5
#define PRESET_READ_BUF_LEN ((PRESET_STRUCT_LEN * PRESET_NUM) + PRESET_READ_BUF_HEADER)

#define PRESET_NAME_OFS  3
#define PRESET_NAME_LEN  28

typedef struct t_Preset {
    char          name[PRESET_NAME_LEN];
    int           chargeC;
    float         chargeCurrent;
    float         chargeVoltage;
    float         dischargeCurrent;
    float         dischargeVoltage;
} Preset;
#endif // COMM_H
